package com.wry.file.utils;

import com.deepoove.poi.policy.DynamicTableRenderPolicy;
import com.deepoove.poi.util.TableTools;
import com.wry.file.controller.WordController;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

import java.util.List;
import java.util.Map;

/**
 * <h1>  <h1>
 *
 * @author wry
 * @since 2024/9/10 8:56
 */
public class WordTableUtil {

    /**
     * 字段对应表格中的索引位置
     */
    static Map<String,Integer> FIELD_INDEX_MAP = Map.of(
            "no",0,
            "cnName",1,
            "enName",2,
            "goal",3,
            "inNo",4,
            "remark",5
    );

    private static final List<Integer> NEED_MERGE_FILED_FIELD_LIST = List.of(FIELD_INDEX_MAP.get("no"), FIELD_INDEX_MAP.get("goal"));

    public static class TableMergePolicy01 extends DynamicTableRenderPolicy {
        @Override
        public void render(XWPFTable table, Object data) throws Exception {
            if (data == null){
                return;
            }
            List<WordController.GoodsInfo> goodsInfoList = (List<WordController.GoodsInfo>) data;
            if (goodsInfoList.isEmpty()) return;
            // 表头行作为样式基准（模板只有表头行）
            XWPFTableRow headerRow = table.getRow(0);
            if (headerRow == null) {
                throw new NullPointerException("表头行不存在，请确保模板中有表头行。");
            }
            // 记录上一行的使用目的，来判断是否合并
            String previousGoal = null;
            // 合并的起始行，跳过标题行
            // 指针记录合并的起始行
            int pointerRow = 1;
            for (int row = 0; row < goodsInfoList.size(); row++) {
                // 当前行
                WordController.GoodsInfo current = goodsInfoList.get(row);

                // 创建新行，并复制表头行的结构和样式
                XWPFTableRow newRow = table.createRow();
                copyRowStyle(headerRow, newRow);

                newRow.getCell(FIELD_INDEX_MAP.get("cnName")).setText(current.getCnName());  // 中文名称
                newRow.getCell(FIELD_INDEX_MAP.get("enName")).setText(current.getEnName());  // INCI名称/英文名称
                newRow.getCell(FIELD_INDEX_MAP.get("inNo")).setText(current.getInNo().toString());  // 在《已使用原料目录》中的序号
                newRow.getCell(FIELD_INDEX_MAP.get("remark")).setText(current.getRemark());  // 备注

                // 如果当前使用目的与上一行相同，清空当前行的序号和使用目的
                if (current.getGoal().equals(previousGoal)) {
                    newRow.getCell(FIELD_INDEX_MAP.get("no")).setText("");
                    newRow.getCell(FIELD_INDEX_MAP.get("goal")).setText("");
                } else {
                    // 使用目的不相同，填充序号和使用目的具体值
                    newRow.getCell(FIELD_INDEX_MAP.get("no")).setText(current.getNo().toString());  // 序号
                    newRow.getCell(FIELD_INDEX_MAP.get("goal")).setText(current.getGoal());  // 使用目的
                    // 合并上一组相同使用目的的行
                    if (previousGoal != null && row > pointerRow) {
                        mergeCells(table, pointerRow, row);
                    }
                    // 指针向当前行后移一个
                    pointerRow = row + 1; // 更新到当前行的下一行
                    previousGoal = current.getGoal();  // 更新之前的使用目的
                }
            }
            // 处理最后一组的合并
            if (pointerRow < goodsInfoList.size()) {
                mergeCells(table, pointerRow, goodsInfoList.size());
            }
        }

        /**
         * 复制表头行的样式
         *
         * @param headerRow 表头行
         * @param targetRow 目标行
         */
        private void copyRowStyle(XWPFTableRow headerRow, XWPFTableRow targetRow) {
            for (int i = 0; i < headerRow.getTableCells().size(); i++) {
                if (targetRow.getCell(i) == null) {
                    targetRow.createCell();
                }
                targetRow.getCell(i).getCTTc().setTcPr(headerRow.getCell(i).getCTTc().getTcPr());
            }
        }

        /**
         * 合并单元格
         *
         * @param table
         * @param startRow 开始行
         * @param endRow   结束行
         */
        private void mergeCells(XWPFTable table, int startRow, int endRow) {
            for (Integer index : NEED_MERGE_FILED_FIELD_LIST) {
                TableTools.mergeCellsVertically(table, index, startRow, endRow);
            }
        }
    }
}
